package msgCenter;

import java.util.Vector;

import preferMgr.XonePrefHelper;
import Utils.XoneUtil;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.ConnectivityManager;
import android.os.IBinder;
import android.os.RemoteException;

import com.netease.log.NTLog;
import com.netease.pkgRelated.XoneConsts;
import com.netease.push.IPushCallBack;
import com.netease.push.IPushService;
import com.netease.push.PushSetting;
import com.netease.util.PhoneUtil;
import com.netease.xone.notification.NotificationBarMgr;

public class MsgCenter {
	private static String TAG = "msgCenter";
	
	public final static int TYPE_MSG = 0;
	public final static int TYPE_MAIL = 1;
	public final static int TYPE_NULL = -1;
	
	private Context mContext;
	private IPushService mPushService;

	private boolean mServiceStarted;
	//service起来之前的等待标记
	private boolean mbWaitStartPush = false;
	private boolean mbWaitStartPolling = false;
	private long mLastMsgId = -1;
	private boolean isAppExit = false;
	
	private static MsgCenter sIns;
	private Vector<OnMsgPushListener> mOnMsgPushListeners;
	
	public static MsgCenter getInstance(Context context){
		if (sIns == null) {
			sIns = new MsgCenter(context);
		}

		return sIns;
	}
	
	private MsgCenter(Context context) {
		mContext = context;
		mOnMsgPushListeners = new Vector<OnMsgPushListener>();
	}
	public void addListener(OnMsgPushListener onMsgPushListener) {
        synchronized (mOnMsgPushListeners) {
            mOnMsgPushListeners.add(onMsgPushListener);
        }
    }
    
    public void removeListener(OnMsgPushListener onMsgPushListener) {
        synchronized (mOnMsgPushListeners) {
            mOnMsgPushListeners.remove(onMsgPushListener);
        }
    }
    public void setAppExit(boolean exit) {
        isAppExit = exit;
    }
  //通知需要刷新消息数的界面刷新
    private void notifyMainNewsInfo(int type) {
        synchronized (mOnMsgPushListeners) {
            for (int i = 0; i < mOnMsgPushListeners.size(); i++) {
                OnMsgPushListener onMsgPushListener = mOnMsgPushListeners.get(i);
                onMsgPushListener.onFreshPushInfo(type);
            }
        }
    }
	
	/**
	 * 启动服务
	 */
	public void launchService() {
		// 以下情况会主动关闭服务：
		//  1、网络已经断开； 
		//	2、不开启push服务
		if(!PhoneUtil.hasConnected(mContext) || !PushSetting.isPushSettingOpen(mContext)){
			stopService();
			return;
		}
		
		// 服务是否已经启动
		if (mServiceStarted) {
			return;
		}

		Intent intent = getServiceIntent();
		mContext.startService(intent);
		mContext.bindService(intent, mServiceConnection, Service.BIND_AUTO_CREATE);
		mServiceStarted = true;
	}
	
	/**
	 * 停止服务
	 */
	public void stopService() {
		if (!mServiceStarted) {
			return;
		}
		
		stopPush();

		sIns = null;
		mServiceStarted = false;
		mbWaitStartPush = false;
		mbWaitStartPolling = false;
		
		if (mPushService != null) {
			mContext.unbindService(mServiceConnection);
			mPushService = null;
		}
		
		Intent intent = getServiceIntent();
		mContext.stopService(intent);
	}
	
	/**
	 * 取得需要操作服务的Intent对象
	 * @return
	 */
	private Intent getServiceIntent() {
		String packageName = mContext.getPackageName();
		Intent intent = new Intent();
		intent.setAction(packageName + ".ACTION");
		intent.addCategory(packageName + ".CATEGORY");
		
		return intent;
	}
	
	/**
	 * 是否已经开启服务
	 * @return
	 */
	private boolean isServiceConnected() {
		return mPushService != null;
	}
	
	/**
	 * 是否有网络
	 * @return
	 */
	@SuppressWarnings("deprecation")
    public boolean isBackgroundDataEnabled() {
        ConnectivityManager manager =
                (ConnectivityManager) mContext.getSystemService(mContext.CONNECTIVITY_SERVICE);
        return manager.getBackgroundDataSetting();
    }
	
	/**
	 * 重启push服务, push服务由service自己启动
	 */
	public void reStartPush() {
		NTLog.i(TAG, "startPush()" + isServiceConnected());
		
		if(!PushSetting.isPushSettingOpen(mContext) || !isBackgroundDataEnabled()){
			return;
		}
		
		mbWaitStartPush = false;
		if (mPushService != null) {
			try {
				mPushService.reStartPush();
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
		else {
			mbWaitStartPush = true;
		}
	}
	
	/**
	 * 停止Push服务
	 */
	public void stopPush() {
		NTLog.i(TAG, "stopPush()" + isServiceConnected());
		mbWaitStartPush = false;
		if (mPushService != null) {
			try {
				mPushService.stopPush();
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 拉消息
	 */
	public void pollingIm(long lastMsgId){
		NTLog.i(TAG, "pollingIm()" + isServiceConnected());
		mbWaitStartPolling = false;
		if (mPushService != null) {
			try {
				mPushService.pollingIm(lastMsgId);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
		else {
			mbWaitStartPolling = true;
			mLastMsgId = lastMsgId;
		}
	}
	
	public void resetClientFeature(){
		if (mPushService != null) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						mPushService.resetClientFeature();
					} catch (RemoteException e) {
						e.printStackTrace();
					}
				}
			}).start();
		}
		else {
			launchService();
		}
	}
	
	
	private ServiceConnection mServiceConnection = new ServiceConnection() {
		
		 @Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			 mPushService = IPushService.Stub.asInterface(service);
			 try {
				mPushService.addPushCallback(mPushCallBack);
				
				if(mbWaitStartPush){
					mPushService.reStartPush();
				}

				if(mbWaitStartPolling){
					mPushService.pollingIm(mLastMsgId);
				}
				
				mbWaitStartPush = false;
				mbWaitStartPolling = false;
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
		 
		@Override
		public void onServiceDisconnected(ComponentName name) {
			if (mPushService != null) {
				try {
					mPushService.removePushCallback(mPushCallBack);
				} catch (RemoteException e) {
					e.printStackTrace();
				}
				mPushService = null;
			}
		}
	};
	
	private IPushCallBack mPushCallBack = new IPushCallBack.Stub() {
		
		@Override
		public void onMessage(int code, int arg1, int arg2, String arg3)
				throws RemoteException {
		    NTLog.i(TAG, "onMessage:" + arg3);  
			PushMsgParse parse = PushMsgParse.parseJson(arg3);
			processMessagePush(parse);
		}
		
		@Override
		public void onError(int errCode, int arg1, int arg2, String arg3)
				throws RemoteException {
			NTLog.i(TAG, "onError:" + arg3);	
		}
	};
	private void processMessagePush(PushMsgParse parse){
        // 消息是否已经存在，为了去重消息，因为有两个发送端（GCM和Push服务器）
        if(parse == null || MsgManager.isPushExist(mContext, parse.msgId)){
            return;//已存在
        }
        boolean notify = true;
        switch (parse.msgType){
            case XoneConsts.PUSHMSG_TYPE.Advice:
                notify = false;
                break;
            case XoneConsts.PUSHMSG_TYPE.PrivateMsg:
                notify = XonePrefHelper.getPushOn(mContext) && XonePrefHelper.getNewMessageOn(mContext);
                break;
            case XoneConsts.PUSHMSG_TYPE.AtMe:
                notify = XonePrefHelper.getPushOn(mContext) && XonePrefHelper.getAtMeOn(mContext);
                break;
            case XoneConsts.PUSHMSG_TYPE.Comment:
                notify = XonePrefHelper.getPushOn(mContext) && XonePrefHelper.getNewCommentOn(mContext);
                break;
            case XoneConsts.PUSHMSG_TYPE.Praise:
                notify = XonePrefHelper.getPushOn(mContext) && XonePrefHelper.getNewPraiseOn(mContext);
                break;
            case XoneConsts.PUSHMSG_TYPE.Dynamic:
                notify = XonePrefHelper.getPushOn(mContext) && XonePrefHelper.getNewFriendDynamicOn(mContext);
                break;
            case XoneConsts.PUSHMSG_TYPE.NewFans:
                notify = XonePrefHelper.getPushOn(mContext) && XonePrefHelper.getNewFansOn(mContext);
                break;
        }
        if(notify){
            MsgManager.insertPushMsg(mContext, parse, false);
            notify &= !XoneUtil.isTopActivity(mContext);//判断应用是否在前台，前台不提醒
        }
        if(notify){
            int count = MsgManager.getMsgCountByType(mContext, parse.msgType);
            if(count >0 ){
                NotificationBarMgr.getInstance(mContext).showPushMessage(parse.msgType, count);
            }  
        }
        notifyMainNewsInfo(parse.msgType);
    }
	/**
	 * 回调函数，如果界面要对消息的变化产生变动，需要注册该消息
	 *
	 */
	public interface OnMsgPushListener {
		/**
		 * 
		 * @param type    消息类型，Mail，Msg，Null
		 * @param msgCount
		 * @param mailCount
		 */
		public void onFreshPushInfo(int type);
	}
}